<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <link rel="shortcut icon" href="img/favicon.ico">
  <title>物品栏和背包 - Minetest Modding Books(中文版)</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700" />

  <link rel="stylesheet" href="css/theme.css" />
  <link rel="stylesheet" href="css/theme_extra.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/github.min.css" />
  
  <script>
    // Current page data
    var mkdocs_page_name = "\u7269\u54c1\u680f\u548c\u80cc\u5305";
    var mkdocs_page_input_path = "8.\u7269\u54c1\u680f\u548c\u80cc\u5305.md";
    var mkdocs_page_url = null;
  </script>
  
  <script src="js/jquery-2.1.1.min.js" defer></script>
  <script src="js/modernizr-2.8.3.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script> 
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
        <a href="index.html" class="icon icon-home"> Minetest Modding Books(中文版)</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="./search.html" method="get">
      <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="index.html">首页</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="1.%E8%AF%91%E8%80%85%E5%BA%8F.html">译者序</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="2.%E5%89%8D%E8%A8%80.html">前言</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="3.%E5%85%A5%E9%97%A8.html">入门</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="4.Lua%E8%84%9A%E6%9C%AC.html">Lua脚本</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="5.%E8%8A%82%E7%82%B9%E3%80%81%E7%89%A9%E5%93%81%E5%92%8C%E5%88%B6%E4%BD%9C.html">节点、物品与制作</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="6.%E5%88%B6%E4%BD%9C%E6%9D%90%E8%B4%A8.html">制作贴图</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="7.%E8%8A%82%E7%82%B9%E7%BB%98%E5%9B%BE%E7%B1%BB%E5%9E%8B.html">节点绘图类型</a>
                    </li>
                </ul>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="8.%E7%89%A9%E5%93%81%E6%A0%8F%E5%92%8C%E8%83%8C%E5%8C%85.html">物品栏和背包</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#_2">什么是物品库（或者是玩家背包）？</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#_3">物品栏</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#_4">物品库的位置</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#_5">列表</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#_6">大小和宽度</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#_7">检查内容</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#_8">修改库存和物品栏</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#_9">添加到一个列表中</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#_10">拿东西</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#_11">操作物品栏</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#_12">磨损</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#lua">Lua表</a>
    </li>
    </ul>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="9.%E5%9F%BA%E6%9C%AC%E5%9C%B0%E5%9B%BE%E6%93%8D%E4%BD%9C.html">基本地图操作</a>
                    </li>
                </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href="index.html">Minetest Modding Books(中文版)</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href="index.html">Docs</a> &raquo;</li>
    
      
    
    <li>物品栏和背包</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  
  <hr/>
</div>

          <div role="main">
            <div class="section">
              
                <h1 id="_1">物品栏和背包</h1>
<p>在这一章节中，你将知道如何使用和控制背包，或许是玩家的背包（物品库），或者是节点中的物品库，或者是独立的物品库。</p>
<h2 id="_2">什么是物品库（或者是玩家背包）？</h2>
<p>一个物品栏是清单中单个单元格后面的数据。<br/>
库存是库存列表的集合，每个列表都是物品栏的二维网格。清单在清单的上下文中简称为清单。当玩家和节点最多只有一个物品库时，物品库的重点是允许多个网格。<br/></p>
<h2 id="_3">物品栏</h2>
<p>物品栏有三个组件。<br/>
项名称可以是已注册项的项名称、别名或未知项名称。当用户卸载mods或mods在没有预防措施（如注册别名）的情况下删除项时，未知项很常见。</p>
<pre><code class="language-lua">print(stack:get_name())
stack:set_name(&quot;default:dirt&quot;)

if not stack:is_known() then
    print(&quot;Is an unknown item!&quot;)
end
</code></pre>
<p>计数将始终为0或更大。通过正常的游戏，计数应该不超过项目堆栈最大的堆栈大小(<code>stack_max</code>)。但是，管理命令和错误模式可能导致堆栈超过最大大小。</p>
<pre><code class="language-lua">print(stack:get_stack_max())
</code></pre>
<p>ItemStack可以为空，在这种情况下，计数将为0。</p>
<pre><code class="language-lua">print(stack:get_count())
stack:set_count(10)
</code></pre>
<p>可以使用ItemStack函数以多种方式构造ItemStack。</p>
<pre><code class="language-lua">ItemStack() -- name=&quot;&quot;, count=0
ItemStack(&quot;default:pick_stone&quot;) -- count=1
ItemStack(&quot;default:stone 30&quot;)
ItemStack({ name = &quot;default:wood&quot;, count = 10 })
</code></pre>
<p>项目元数据是有关该项目的数据的不受限制的键值存储。键值意味着您使用一个名称（称为键）来访问数据（称为值）。有些键有特殊的含义，例如<code>description</code>，用于对每个堆栈项进行描述。这将在元数据和存储一章中详细介绍。</p>
<h2 id="_4">物品库的位置</h2>
<p>物品库位置是背包存储的位置和方式。物品库位置有三种类型：player、node和detached。物品库直接绑定到一个而且只有一个位置-更新库存将导致它立即更新。<br>
节点清单与特定节点（如胸部）的位置相关。必须加载节点，因为它存储在<a href="https://rubenwardy.com/minetest_modding_book/en/map/storage.html#metadata">节点元数据(未翻译)</a>中。</p>
<pre><code class="language-lua">local inv = minetest.get_inventory({ type=&quot;node&quot;, pos={x=1, y=2, z=3} })
</code></pre>
<p>上面得到一个<em>物品库引用</em>，通常称为<em>InvRef</em>。物品库引用用于操作库存。<em>引用</em>意味着数据实际上并不存储在该对象中，而是直接就地更新数据。<br>
举个例子：</p>
<pre><code class="language-lua">local location = inv:get_location()
</code></pre>
<p>玩家物品库可以类似地获得或使用玩家参考。玩家必须在线才能访问他们的物品库。</p>
<pre><code class="language-lua">local inv = minetest.get_inventory({ type=&quot;player&quot;, name=&quot;player1&quot; })
-- or
local inv = player:get_inventory()
</code></pre>
<p>独立库存物品库是独立于参与者或节点的物品库。独立物品库也不会在重新启动时保存。需要先创建独立物品库，然后才能使用它们——这个将在稍后讨论。</p>
<pre><code class="language-lua">local inv = minetest.get_inventory({
    type=&quot;detached&quot;, name=&quot;inventory_name&quot; })
</code></pre>
<p>与其他类型的库存不同，必须首先创建分离的库存：</p>
<pre><code class="language-lua">minetest.create_detached_inventory(&quot;inventory_name&quot;)
</code></pre>
<p>create_detached_inventory函数接受3个参数，只需要第一个参数。第二个参数采用回调表，该表可用于控制玩家如何与物品库交互：</p>
<pre><code class="language-lua">-- Input only detached inventory
minetest.create_detached_inventory(&quot;inventory_name&quot;, {
    allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
        return count -- allow moving
    end,

    allow_put = function(inv, listname, index, stack, player)
        return stack:get_count() -- allow putting
    end,

    allow_take = function(inv, listname, index, stack, player)
        return -1 -- don't allow taking
    end,

    on_put = function(inv, listname, index, stack, player)
        minetest.chat_send_all(player:get_player_name() ..
            &quot; gave &quot; .. stack:to_string() ..
            &quot; to the donation chest at &quot; .. minetest.pos_to_str(pos))
    end,
})
</code></pre>
<p>权限回调——以<code>allow_</code>开头的回调返回要传输的项目数，其中-1用于完全阻止传输。<br>
操作回调——以<code>on_</code>为开头——没有返回值，无法阻止传输。</p>
<h2 id="_5">列表</h2>
<p>物品库列表是一个概念，用于允许多个网格存储在一个位置。这对玩家来说尤其有用，因为所有游戏都有一些常见的列表，例如主目录和<em>工艺</em>槽。</p>
<h3 id="_6">大小和宽度</h3>
<p>列表有一个大小（网格中单元格的总数）和一个宽度（仅在引擎中使用）。在窗口中绘制清单时不使用列表的宽度，因为窗口后面的代码决定要使用的宽度。</p>
<pre><code class="language-lua">if inv:set_size(&quot;main&quot;, 32) then
    inv:set_width(&quot;main&quot;, 8)
    print(&quot;size:  &quot; .. inv.get_size(&quot;main&quot;))
    print(&quot;width: &quot; .. inv:get_width(&quot;main&quot;))
else
    print(&quot;Error! Invalid itemname or size to set_size()&quot;)
end
</code></pre>
<p>如果列表名或大小无效，则<code>set_size</code>将失败并返回false。例如，新大小可能太小，无法容纳库存中的所有当前项。</p>
<h3 id="_7">检查内容</h3>
<p><code>is_empty</code>可用于查看列表是否包含任何项：</p>
<pre><code class="language-lua">if inv:is_empty(&quot;main&quot;) then
    print(&quot;The list is empty!&quot;)
end
</code></pre>
<p><code>contains_item</code> can be used to see if a list contains a specific item.</p>
<h2 id="_8">修改库存和物品栏</h2>
<h3 id="_9">添加到一个列表中</h3>
<p>要将项添加到名为<code>"main"</code>的列表中，同时考虑最大堆栈大小，请执行以下操作：</p>
<pre><code class="language-lua">local stack    = ItemStack(&quot;default:stone 99&quot;)
local leftover = inv:add_item(&quot;main&quot;, stack)
if leftover:get_count() &gt; 0 then
    print(&quot;Inventory is full! &quot; ..
            leftover:get_count() .. &quot; items weren't added&quot;)
end
</code></pre>
<h3 id="_10">拿东西</h3>
<p>从一个列表中移除某样东西：</p>
<pre><code class="language-lua">local taken = inv:remove_item(&quot;main&quot;, stack)
print(&quot;Took &quot; .. taken:get_count())
</code></pre>
<h3 id="_11">操作物品栏</h3>
<p>你可以先修改单个物品栏：</p>
<pre><code class="language-lua">local stack = inv:get_stack(listname, 0)
</code></pre>
<p>然后通过设置属性或使用与<code>stack_size</code>相关的方法修改它们：</p>
<pre><code class="language-lua">local stack    = ItemStack(&quot;default:stone 50&quot;)
local to_add   = ItemStack(&quot;default:stone 100&quot;)
local leftover = stack:add_item(to_add)
local taken    = stack:take_item(19)

print(&quot;Could not add&quot;  .. leftover:get_count() .. &quot; of the items.&quot;)
-- ^ will be 51

print(&quot;Have &quot; .. stack:get_count() .. &quot; items&quot;)
-- ^ will be 80
--   min(50+100, stack_max) - 19 = 80
--     where stack_max = 99
</code></pre>
<p><code>add_item</code>将向物品栏添加项并返回任何无法添加的项。<code>take_item</code>将占用最多的项目数，但可能占用较少的项目数，并返回所占用的物品栏。
最后，设定物品栏：</p>
<pre><code class="language-lua">inv:set_stack(listname, 0, stack)
</code></pre>
<h2 id="_12">磨损</h2>
<p>工具可能有磨损；磨损显示进度条，完全磨损时会使工具彻底报废。磨损值最高为65535；磨损越高，工具磨损越严重。<br>
磨损可以使用<code>add_wear()</code>、<code>get_wear()</code>和<code>set_wear(wear)</code>进行操作。</p>
<pre><code class="language-lua">local stack = ItemStack(&quot;default:pick_mese&quot;)
local max_uses = 10

-- This is done automatically when you use a tool that digs things
-- It increases the wear of an item by one use.
stack:add_wear(65535 / (max_uses - 1))
</code></pre>
<p>挖掘节点时，工具的磨损量可能取决于正在挖掘的节点。因此，max_uses的用途因挖掘的对象而异。</p>
<h2 id="lua">Lua表</h2>
<p>物品栏和库存可以转换为表和表。这对于复制和批量操作很有用。</p>
<pre><code class="language-lua">-- Entire inventory
local data = inv1:get_lists()
inv2:set_lists(data)

-- One list
local listdata = inv1:get_list(&quot;main&quot;)
inv2:set_list(&quot;main&quot;, listdata)
</code></pre>
<p><code>get_lists()</code>返回的列表表如下：</p>
<pre><code class="language-lua">{
    list_one = {
        ItemStack,
        ItemStack,
        ItemStack,
        ItemStack,
        -- inv:get_size(&quot;list_one&quot;) elements
    },
    list_two = {
        ItemStack,
        ItemStack,
        ItemStack,
        ItemStack,
        -- inv:get_size(&quot;list_two&quot;) elements
    }
}
</code></pre>
<p><code>get_list()</code>将返回单个列表作为物品栏列表。<br>
需要注意的一点是，上面的set方法不会改变列表的大小。这意味着您可以通过将列表设置为空表来清除列表，并且不会减小其大小：</p>
<pre><code class="language-lua">inv:set_list(&quot;main&quot;, {})
</code></pre>
              
            </div>
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="9.%E5%9F%BA%E6%9C%AC%E5%9C%B0%E5%9B%BE%E6%93%8D%E4%BD%9C.html" class="btn btn-neutral float-right" title="基本地图操作">Next <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="7.%E8%8A%82%E7%82%B9%E7%BB%98%E5%9B%BE%E7%B1%BB%E5%9E%8B.html" class="btn btn-neutral" title="节点绘图类型"><span class="icon icon-circle-arrow-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
    
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
      
        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="versions">
  <span class="rst-current-version" data-toggle="rst-current-version">
    
    
      <span><a href="7.%E8%8A%82%E7%82%B9%E7%BB%98%E5%9B%BE%E7%B1%BB%E5%9E%8B.html" style="color: #fcfcfc">&laquo; Previous</a></span>
    
    
      <span><a href="9.%E5%9F%BA%E6%9C%AC%E5%9C%B0%E5%9B%BE%E6%93%8D%E4%BD%9C.html" style="color: #fcfcfc">Next &raquo;</a></span>
    
  </span>
</div>
    <script>var base_url = '.';</script>
    <script src="js/theme_extra.js" defer></script>
    <script src="js/theme.js" defer></script>
      <script src="search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
